#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/of.h> 
#include <linux/miscdevice.h>
#include <linux/fs.h>//file_openrations
#include <linux/of_gpio.h>
#include <linux/gpio.h>
struct device_node *dev;//描述一个节点
struct property *pro;//属性信息
int beep_gpio;
ssize_t misc_read(struct file *fd,char __user *buf,size_t len,loff_t *off)
{
    return len;
}
ssize_t misc_write(struct file *fd,const char __user *buf,size_t len,loff_t *off)
{
    if(buf[0] == '0')
    {
        gpio_set_value(beep_gpio,0);
    }
    if (buf[0] == '1')
    {
        gpio_set_value(beep_gpio,1);
    }
    
    return len;
}
int misc_open (struct inode *no,struct file *fd)
{
    printk("open\n");
    return 0;
}
int misc_release(struct inode *no,struct file *fd)
{
    printk("release\n");
    return 0;
}
struct file_operations misc_fops = {
    .open = misc_open,
    .release = misc_release,
    .read = misc_read,
    .write = misc_write,
};
struct miscdevice misc_dev = {
    .name = "beep_ctrl",
    .fops = &misc_fops,
};
static int test_init (void)
{
    int ret = 0;
    dev = of_find_node_by_path("/test");
    if(dev == NULL)
    {
        printk("of find node by path is error\n");
        return -1;
    }
    beep_gpio = of_get_named_gpio(dev,"gpios",0);
    if (beep_gpio < 0)
    {
        printk("of_get_named_gpio is error\n");
        return -1;
    }
    ret = gpio_request(beep_gpio,"beep");
    if (ret < 0)
    {
        printk("gpio reauest is error\n");
        return -1;
    }
    ret = gpio_direction_output(beep_gpio ,0);
    if (ret < 0)
    {
        printk("gpio direction is error\n");
    }
    gpio_set_value(beep_gpio,0);
    ret = misc_register(&misc_dev);
    if (ret < 0)
    {
        printk("misc_redister is error\n");
    }
    return 0;
}
static void test_exit(void)
{
    misc_deregister(&misc_dev);
    gpio_free(beep_gpio);
    printk("bye \n");
}
MODULE_LICENSE("GPL");
module_init(test_init);
module_exit(test_exit);